Conversation
| const isServer = typeof window === 'undefined'; | ||
|
|
||
| const fetch = require('node-fetch'); | ||
| const optimizelyClient = createInstance({ |
There was a problem hiding this comment.
this assumes a new instance is created per request. Would be good to document the code example to include the instane creation using the following pattern:
function App() {
const [optimizely] = useState(() => createInstacne({ });
return <OptimizelyProvider optimizely={optimizely}> child </OptimizelyProvider>
}
| datafileOptions: { autoUpdate: !isServer }, | ||
| eventBatchSize: isServer ? 1 : 10, | ||
| eventMaxQueueSize: isServer ? 1 : 100, | ||
| // Optional: disable decision events on server if they will be sent from the client |
There was a problem hiding this comment.
I think odp event manager also has background timers, need to provided appropriate option for that
| // src/data/getDatafile.ts | ||
| const CDN_URL = `https://cdn.optimizely.com/datafiles/${process.env.NEXT_PUBLIC_OPTIMIZELY_SDK_KEY}.json`; | ||
|
|
||
| export async function getDatafile() { |
There was a problem hiding this comment.
one potential issue with this is that the ssr rendered component will basically always use the statically fetched datafile that was fetched at the beginning. The server side is expected to run for long time and it would miss updates. Basically this function need to pool the datafile as well. But since the sdk already has polling, this function can just use the SDK to do the polling,
// all other options can be turned off, this is just for polling datafile
const pollingInstance = createInstance({ sdkKey });
export async function getDatafile() {
await pollingInstance.onReady();
return pollingInstance.getOptimizelyConfig().getDatafile();
}
| const [optimizely] = useState(() => { | ||
| const isServer = typeof window === 'undefined'; | ||
| return createInstance({ | ||
| datafile, |
There was a problem hiding this comment.
would be good to include the sdkKey as well (would be used for config updaes in the client side)
|
|
||
| - **Datafile required** — SSR requires a pre-fetched datafile. Using `sdkKey` alone falls back to a failed decision. | ||
| - **Static user only** — User `Promise` is not supported during SSR. | ||
| - **ODP segments unavailable** — ODP audience segments require async I/O and are not available during server rendering. |
There was a problem hiding this comment.
since there is a change in the hooks.ts file, I assume we need a patch update. In that case, can we consider adding the option to pass pre-fetched qualifiedSegments as props to the release?
|
|
||
| ```tsx | ||
| // pages/index.tsx | ||
| export async function getServerSideProps() { |
There was a problem hiding this comment.
similar here as the app router. instead of fetching on every request, we can have one optimizely instance for polling and get the datafile form the instance
| } | ||
| ``` | ||
|
|
||
| ### Static user only |
There was a problem hiding this comment.
Static user only might suggest user cannot be changed, maybe use User Promise not supported?
Summary
This pull request improves the documentation and implementation of server-side rendering (SSR) and ODP segment handling in the Optimizely React SDK V3.
It clarifies SSR usage in the README, adds a comprehensive Next.js integration guide, and updates the SDK's hooks to support more accurate decision-making during partial readiness states (such as when ODP segments are still being fetched). It also enhances test coverage for these scenarios.
Documentation improvements:
README.mdto explain the need for a pre-fetched datafile, updated setup instructions, and added a summary of SSR limitations. References to Next.js and React Server Components were added, and the SSR example was simplified.docs/nextjs-ssr.mdguide detailing integration patterns for both Next.js App Router and Pages Router, including code examples, feature flag usage, server component usage, and SSR limitations.SDK logic and behavior changes:
useExperiment,useFeature, anduseDecisionhooks to support synchronous decisions whengetOptimizelyConfigandgetUserContextare available, even if the client is not fully ready (e.g., ODP segments are still loading). This enables partial decisions during SSR or while waiting for async user/segment data. [1] [2] [3]Testing improvements:
Experiment.spec.tsx,Feature.spec.tsx, andhooks.spec.tsxto includegetOptimizelyConfigandgetUserContextmethods, simulating partial readiness and ODP scenarios. [1] [2] [3]Minor documentation and formatting fixes:
README.mdfor clarity and consistency. [1] [2] [3] [4] [5]These changes make SSR and ODP segment handling more robust and developer-friendly, especially for teams using Next.js or requiring partial readiness support.
Test plan
Issues